#!/usr/bin/env python
#-*- coding:utf-8 -*-
######################################################################
## Filename:      calc.py
##                
## Copyright (C) 2009,  renewjoy
## Version:       0.1
## Author:        renewjoy <rlj_linux@126.com>
## Created at:    Sun Jul  5 01:19:55 2009
##                
## Description:   pygtk+glade实现简单的计算器
##                
######################################################################

import gtk
import gtk.glade

# 计算器类
class calc:
    def __init__(self):
        self.first = ''                          # 被加数（第一个数）
        self.second = ''                         # 加数（第二个数）
        self.is_first = True                     # 是第一个数的标志吗？
        self.first_no_point = True    # 第一个数还没有小数点
        self.second_no_point = True   # 第二个数还没有小数点

        # 定义所使用的glade文件
        self.glade_file = "calc.glade"  

        # 将界面导入到self.main_window
        self.main_window = gtk.glade.XML(self.glade_file)

        # 连接widget
        self.window = self.main_window.get_widget ("calc_window")

        # 建立一个字典，描述各个信号的处理函数
        events_dic = {"on_calc_window_destroy":gtk.main_quit, # 退出
                      "on_button1_clicked":self.handle_1_clicked,
                      "on_button2_clicked":self.handle_2_clicked,
                      "on_button3_clicked":self.handle_3_clicked,
                      "on_button4_clicked":self.handle_4_clicked,
                      "on_button5_clicked":self.handle_5_clicked,
                      "on_button6_clicked":self.handle_6_clicked,
                      "on_button7_clicked":self.handle_7_clicked,
                      "on_button8_clicked":self.handle_8_clicked,
                      "on_button9_clicked":self.handle_9_clicked,
                      "on_button0_clicked":self.handle_0_clicked,
                      "on_button_point_clicked":self.handle_point_clicked,
                      "on_button_add_clicked": (self.handle_operator_clicked, '+'), # 加法
                      "on_button_minus_clicked": (self.handle_operator_clicked,'-'), # 减法
                      "on_button_mutil_clicked": (self.handle_operator_clicked,'*'), # 乘法
                      "on_button_div_clicked": (self.handle_operator_clicked, '/'), # 除法
                      "on_button_equal_clicked":self.handle_equal_clicked, # 计算结果
                      "on_button_backspace_clicked": self.handle_backspace_clicked, # 退格
                      "on_button_clear_clicked": self.handle_clear_clicked, # 消除
                      }
        # 事件自动连接
        self.main_window.signal_autoconnect(events_dic)

        # 获得widget
        self.entry_res = self.main_window.get_widget("entry_result")

        # 显示主窗口
        self.window.show()              # 显示主窗口

    # 定义各个按钮的clicked事件处理函数
    # 单击按钮1
    def handle_1_clicked(self, widget):
        if self.is_first == True:
            self.first += '1'           # 字符串连接
            self.entry_res.set_text(self.first) # 显示当前的数
        else:
            self.second += '1'
            self.entry_res.set_text(self.second)

    # 单击按钮2
    def handle_2_clicked(self, widget):
        if self.is_first:
            self.first += '2'
            self.entry_res.set_text(self.first)
        else:
            self.second += '2'
            self.entry_res.set_text(self.second)

    # 单击按钮3
    def handle_3_clicked(self, widget):
        if self.is_first:
            self.first += '3'
            self.entry_res.set_text(self.first)
        else:
            self.second += '3'
            self.entry_res.set_text(self.second)

    # 单击按钮4
    def handle_4_clicked(self, widget):
        if self.is_first:
            self.first += '4'
            self.entry_res.set_text(self.first)
        else:
            self.second += '4'
            self.entry_res.set_text(self.second)

    # 单击按钮5
    def handle_5_clicked(self, widget):
        if self.is_first:
            self.first += '5'
            self.entry_res.set_text(self.first)
        else:
            self.second += '5'
            self.entry_res.set_text(self.second)

    # 单击按钮6
    def handle_6_clicked(self, widget):
        if self.is_first:
            self.first += '6'
            self.entry_res.set_text(self.first)
        else:
            self.second += '6'
            self.entry_res.set_text(self.second)

    # 单击按钮7
    def handle_7_clicked(self, widget):
        if self.is_first:
            self.first += '7'
            self.entry_res.set_text(self.first)
        else:
            self.second += '7'
            self.entry_res.set_text(self.second)

    # 单击按钮8
    def handle_8_clicked(self, widget):
        if self.is_first:
            self.first += '8'
            self.entry_res.set_text(self.first)
        else:
            self.second += '8'
            self.entry_res.set_text(self.second)

    # 单击按钮9
    def handle_9_clicked(self, widget):
        if self.is_first:
            self.first += '9'
            self.entry_res.set_text(self.first)
        else:
            self.second += '9'
            self.entry_res.set_text(self.second)

    # 单击按钮0
    def handle_0_clicked(self, widget):
        if self.is_first:
            self.first += '0'
            self.entry_res.set_text(self.first)
        else:
            self.second += '0'
            self.entry_res.set_text(self.second)

    # 单击按钮.(point)
    def handle_point_clicked(self, widget):
        if self.is_first:               # 是第一个数
            if self.first_no_point :  # 第一个数还没有小数点吗?
                self.first += '.'
                self.entry_res.set_text(self.first)
                self.first_no_point = False # 已经有一个小数点了
        else:
            if self.second_no_point :  # 第二个数还没有小数点吗?
                self.second += '.'
                self.entry_res.set_text(self.second)
                self.second_no_point = False # 已经有一个小数点了

    # 运算符
    def handle_operator_clicked(self, widget, operator):
        self.is_first = False           # 标志着第二个开始输入
        self.operator = operator        # 获得当前输入的运算符
        self.entry_res.set_text(operator) # 显示运算符

    # 处理结果
    def handle_equal_clicked(self, widget):
        # 没有输入第一个数
        if self.first == "":
            self.first = "0"
        # 没有输入第二个数
        if self.second == "":
            self.second = self.first

        # 进行运算
        if self.operator == "+":
            self.result = float(self.first) + float(self.second)
        elif self.operator == '-':
            self.result = float(self.first) - float(self.second)
        elif self.operator == '*':
            self.result = float(self.first) * float(self.second)
        elif self.operator == '/':
            self.result = float(self.first) / float(self.second)

        self.entry_res.set_text(str(self.result)) # 显示结果

        # 在终端显示运算中间量
        print 'first: %s Second: %s Result: %f' % (self.first, self.second, self.result)
        print 'expression: %s %c %s = %f' % (self.first, self.operator, self.second,self.result)

        # 进行完一次运算后，把标志开始的变量重新设置
        self.first = ""
        self.second = ""
        self.is_first = True            # 标志重新开始输入第一个数
        self.first_no_point = True    # 第一个数还没有小数点
        self.second_no_point = True   # 第二个数还没有小数点


    # 退格函数
    def handle_backspace_clicked(self, widget):
        # 当前正在输入第一个数
        if self.is_first:
            self.first = self.first[0:-1] # 去掉最后一个字符
            # 如果只剩下一个字符时
            if len(self.first) == 0:
                self.entry_res.set_text("0")
            else:
                self.entry_res.set_text(self.first) # 显示
        else:
            self.second = self.second[0:-1]
            # 如果只剩下一个字符时
            if len(self.first) == 0:
                self.entry_res.set_text("0")
            else:
                self.entry_res.set_text(self.second) # 显示    

    # 消除所有，进入下一次运算
    def handle_clear_clicked(self, widget):
        self.first = ""
        self.second = ""
        self.is_first = True            # 标志重新开始输入第一个数

        self.first_no_point = True    # 第一个数还没有小数点
        self.second_no_point = True   # 第二个数还没有小数点

        self.entry_res.set_text("0")


# 函数
def main():
    gtk.main()                          # 主循环，等待事件发生

if __name__ == '__main__':
    calc()                        # 定义一个无名对象
    main()                        # 调用函数
